package com.zthz.douxing

import com.zthz.douxing.msg.ServiceType
import com.zthz.douxing.utils.CommonUtil
import grails.transaction.Transactional
import grails.util.Environment
import groovy.time.TimeCategory
import redis.clients.jedis.Jedis

@Transactional
class PlantripService {

    def tripSegmentEventHandleService
    def redisService

    def updatePlanToHistory(plantripId, saveType) {
        Plantrip plantrip = Plantrip.get(plantripId)
        if(plantrip){
            plantrip.planTripSaveType = saveType
            if(saveType && saveType == PlanTripSaveType.UNDO_EXPIRED) {
                plantrip.segments.each { segment ->
                    tripSegmentEventHandleService.stopJob(segment)
                }
            }
            if(!plantrip.save()) {
                Exception e = new Exception("Plantrip to history updates failed")
                log.error(e.getMessage(),e)
                throw e
            }
        }
    }

    def updateTripSegmentStatus(TripSegment tripSegment, String flag, Date endTime) {
        if (tripSegment) {
            switch (flag) {
                case "1":
                    tripSegment.segmentStatus = SegmentStatus.OnPosition
                    break
                case "2":
                    tripSegment.segmentStatus = SegmentStatus.Arrived
                    if(endTime && endTime?.time - tripSegment.arriveTime.time == 0){
                        def plantripId = tripSegment.plantrip.id
                        updatePlanToHistory(plantripId, PlanTripSaveType.DO_EXPIRED)
                    }
                    break
            }
            if(!tripSegment.save()) {
                Exception e = new Exception("TripSegment's status updates failed")
                log.error(e.getMessage(),e)
                throw e
            }
        }
    }


    def updatePlan(String oldId, Plantrip newplan) {
            //注意处理更新时候的事件
        try{
            Plantrip trip =Plantrip.get(Long.parseLong(oldId))

            if(trip){
                for(TripSegment ts : trip.segments){
                    updateTaskInfon(ts)
                }
                trip.delete()
                if(newplan.save()){
                    generateTaskInfos(newplan)
                }
            }
        }catch (Exception e){
            log.debug(e,e.getMessage())
            throw new RuntimeException()
        }
    }

    def deletePlan(plantripId) {
        try {
            Plantrip trip = Plantrip.get(Long.parseLong(plantripId))
            if(trip?.segments){
                trip?.segments?.each { segment ->
//                    tripSegmentEventHandleService.stopJob(segment)
                    updateTaskInfon(segment)
                }
            }
            trip.delete()
        } catch (e) {
            log.error(e.message, e)
            throw e
        }
    }

    def generateTaskInfos(Plantrip plan){
        boolean isNull = false
        if(plan){
            if(plan.segments){
                for(TripSegment ts : plan.segments){
                    if(!TripSegment.get(ts.id))
                        isNull = true
                }
            }
        }

        if(isNull)
            return
        plan?.segments?.each{TripSegment segment->
            getArrivedMessageTaskInfo(segment)
            getBeginStartGoMessageTaskInfo(segment)
            getArrivedStatusTaskInfo(segment)
            getArrivedBeginStatusTaskInfo(segment)
            getArrivedWeatherTaskInfo(segment)
        }

    }

    private TaskInfo getTaskInfoCommon(TripSegment trip){
        TaskInfo task = new TaskInfo()
        task.boId = trip.id
        task.dateCreated = new Date()
        task.status=0
        return task
    }
    private void getArrivedMessageTaskInfo(TripSegment trip){
        try{
            TaskInfo task = getTaskInfoCommon(trip)
            use(TimeCategory) {
                Date sendTime = null
                sendTime = trip.arriveTime - 10.minutes
                task.dateBeginExe = sendTime
                task.serviceType = ServiceType.arrivedMessageService
                if(task.save()!=null)
                    redisService.sendTaskToQueue(CommonUtil.getJobKey(task.serviceType,task.boId.toString(),sendTime),
                            task.id.toString())
            }
        }catch (Exception e){
            log.error(e.getMessage(),e)
            throw e
        }
    }

    private void getBeginStartGoMessageTaskInfo(TripSegment trip){
        TaskInfo task = getTaskInfoCommon(trip)
        Date now = new Date()
        use(TimeCategory){
            now = now - 5.minutes
                Date sendTime = null
                    Date isLess3HouseFromNow = CommonUtil.getFromDuration2Date(
                            TimeCategory.minus(trip.startTime,(now+3.hours)))

                    if(isLess3HouseFromNow.getTime()<0){
                        sendTime = now
                    }else
                        sendTime = trip.startTime - 3.hours

                    task.serviceType = ServiceType.beginStartGoMessageService
                    task.dateBeginExe = sendTime
                    if(task.save()!=null)
                        redisService.sendTaskToQueue(CommonUtil.getJobKey(task.serviceType,task.boId.toString(),sendTime),task.id.toString())
            }
    }
    private void getArrivedStatusTaskInfo(TripSegment trip){

        TaskInfo task = getTaskInfoCommon(trip)
        task.serviceType = ServiceType.changeArriveStatusService
        task.dateBeginExe = trip.arriveTime
        if(task.save()!=null)
            redisService.sendTaskToQueue(CommonUtil.getJobKey(task.serviceType,task.boId.toString(),trip.arriveTime),task.id.toString())
    }
    private void getArrivedBeginStatusTaskInfo(TripSegment trip){
        TaskInfo task = getTaskInfoCommon(trip)
        task.dateBeginExe = trip.startTime
        task.serviceType = ServiceType.changeBeginStatusService
        try{
            if(task.save())
                redisService.sendTaskToQueue(CommonUtil.getJobKey(task.serviceType,task.boId.toString(),trip.startTime),task.id.toString())
        }catch (Exception e){
            e.printStackTrace()
            log.error(e.getMessage(),e)
        }

    }

    private void getArrivedWeatherTaskInfo(TripSegment trip){
        TaskInfo task = getTaskInfoCommon(trip)
        Date now = new Date()
            Date sendTime
            Date isLess1Day
            use(TimeCategory) {
                now = now - 5.minutes
                    isLess1Day = CommonUtil.getFromDuration2Date(
                            TimeCategory.minus(trip.startTime,(now+1.days))
                    )
                    if(isLess1Day.getTime()<=0){
                        sendTime = now
                    }else{
                        sendTime = trip.startTime - 1.days
                    }
                    task.dateBeginExe = sendTime
                    task.serviceType = ServiceType.weatherMessageService
                    if(task.save()!=null)
                        redisService.sendTaskToQueue(CommonUtil.getJobKey(task.serviceType,task.boId.toString(),sendTime),task.id.toString())
                }
    }
    private void updateTaskInfon(TripSegment segment){
        TaskInfo taskInfo = TaskInfo.findByBoId(segment.id)
        if(taskInfo){
            Set<String> redisDatas = redisService.withRedisHasParameter(
                {Jedis jedis,String keyName ->
                    return jedis.keys(keyName)
                },"${Environment.current.getName()}-*-${segment.id}-*")

            if(redisDatas?.size()>0){
                redisDatas?.each {String key->
                   redisService.withRedisHasParameter(
                            {Jedis jedis,String keyName ->
                                jedis.del(keyName)
                            },key)
                }
            }
            taskInfo.status = 4
            taskInfo.save()
        }else{
            throw new Runtime("未发现TaskInfo")
        }
    }

}
